import { ref, computed, reactive } from 'vue'
import { regionOptimizedApi } from '@/api/regionOptimized'
import { useMemoryCache } from '@/hooks/useCache'
import type { Province, City, District } from '@/api/regionOptimized'
import type { OptimizedRegionSearchResult } from '@/types/regionOptimized'

// 缓存配置
const CACHE_CONFIG = {
  provinces: {
    key: 'region_provinces',
    ttl: 60 * 60 * 1000, // 1小时
  },
  cities: {
    key: (provinceId: number) => `region_cities_${provinceId}`,
    ttl: 30 * 60 * 1000, // 30分钟
  },
  districts: {
    key: (cityId: number) => `region_districts_${cityId}`,
    ttl: 30 * 60 * 1000, // 30分钟
  },
}

/**
 * 地区数据Hook - 优化版
 * 支持缓存、懒加载、错误处理
 */
export function useRegionOptimized() {
  // 响应式数据
  const provinces = ref<Province[]>([])
  const cities = ref<City[]>([])
  const districts = ref<District[]>([])

  // 按省份存储的城市数据
  const citiesByProvince = reactive(new Map<number, City[]>())
  const districtsByCity = reactive(new Map<number, District[]>())

  // 加载状态
  const loadingProvinces = ref(false)
  const loadingCities = ref(false)
  const loadingDistricts = ref(false)

  // 错误状态
  const error = ref<string | null>(null)

  // 缓存Hook - 为每个类型创建独立的缓存实例
  const provincesCache = useMemoryCache<Province[]>()
  const citiesCacheMap = ref(new Map<number, ReturnType<typeof useMemoryCache<City[]>>>())
  const districtsCacheMap = ref(new Map<number, ReturnType<typeof useMemoryCache<District[]>>>())

  // 计算属性
  const regionProvinces = computed(() => provinces.value)
  const regionCities = computed(() => cities.value)
  const regionDistricts = computed(() => districts.value)

  // 计算属性：根据省份ID获取城市
  const getCitiesForProvince = computed(() => (provinceId: number | null | undefined) => {
    if (!provinceId) return []
    const cachedCities = citiesByProvince.get(provinceId)

    // 如果没有缓存数据，尝试从全局cities数组中筛选
    if (!cachedCities || cachedCities.length === 0) {
      return regionCities.value.filter((city: City) => city.parent_id === provinceId)
    }

    return cachedCities || []
  })

  // 计算属性：根据城市ID获取区县
  const getDistrictsForCity = computed(() => (cityId: number | null | undefined) => {
    if (!cityId) return []
    const cachedDistricts = districtsByCity.get(cityId)

    // 如果没有缓存数据，尝试从全局districts数组中筛选
    if (!cachedDistricts || cachedDistricts.length === 0) {
      return regionDistricts.value.filter((district: District) => district.parent_id === cityId)
    }

    return cachedDistricts || []
  })

  // 获取城市缓存实例
  const getCitiesCache = (provinceId: number) => {
    if (!citiesCacheMap.value.has(provinceId)) {
      citiesCacheMap.value.set(provinceId, useMemoryCache<City[]>())
    }
    return citiesCacheMap.value.get(provinceId)!
  }

  // 获取区县缓存实例
  const getDistrictsCache = (cityId: number) => {
    if (!districtsCacheMap.value.has(cityId)) {
      districtsCacheMap.value.set(cityId, useMemoryCache<District[]>())
    }
    return districtsCacheMap.value.get(cityId)!
  }

  // 加载省份数据
  const loadProvinces = async (useCache = true): Promise<Province[]> => {
    try {
      loadingProvinces.value = true
      error.value = null

      // 尝试从缓存获取
      if (useCache) {
        const cached = provincesCache.get(CACHE_CONFIG.provinces.key)
        if (cached && Array.isArray(cached) && cached.length > 0) {
          provinces.value = cached

          return cached
        }
      }

      // 从API获取
      const data = await regionOptimizedApi.getProvinces()

      // 确保数据格式正确
      const validData = Array.isArray(data) ? data : []
      provinces.value = validData

      // 缓存数据
      if (validData.length > 0) {
        provincesCache.set(CACHE_CONFIG.provinces.key, validData, CACHE_CONFIG.provinces.ttl)
      }

      return validData
    } catch (err) {
      error.value = err instanceof Error ? err.message : '加载省份数据失败'

      // 失败时返回空数组，避免页面崩溃
      provinces.value = []
      return []
    } finally {
      loadingProvinces.value = false
    }
  }

  // 加载城市数据
  const loadCities = async (provinceId: number, useCache = true): Promise<City[]> => {
    if (!provinceId || provinceId <= 0) {
      return []
    }

    try {
      loadingCities.value = true
      // 清除之前的错误状态
      error.value = null

      const cacheKey = CACHE_CONFIG.cities.key(provinceId)
      const citiesCache = getCitiesCache(provinceId)

      // 尝试从缓存获取
      if (useCache) {
        const cached = citiesCache.get(cacheKey)
        if (cached && Array.isArray(cached) && cached.length > 0) {
          citiesByProvince.set(provinceId, cached)
          return cached
        }
      }

      // 从API获取
      const data = await regionOptimizedApi.getCities(provinceId)

      // 确保数据格式正确
      const validData = Array.isArray(data) ? data : []

      // 存储到按省份分类的Map中
      citiesByProvince.set(provinceId, validData)

      // 缓存数据
      if (validData.length > 0) {
        citiesCache.set(cacheKey, validData, CACHE_CONFIG.cities.ttl)
      }

      return validData
    } catch (err) {
      // 只有在真正出错时才设置错误信息，空数据或204状态码不算错误
      if (
        err instanceof Error &&
        err.message !== 'No content' &&
        err.message !== 'request canceled' &&
        !err.message.includes('204') &&
        !err.message.includes('ERR_CANCELED')
      ) {
        error.value = '加载城市数据失败'
      }

      // 失败时返回空数组
      return []
    } finally {
      loadingCities.value = false
    }
  }

  // 加载区县数据
  const loadDistricts = async (cityId: number, useCache = true): Promise<District[]> => {
    if (!cityId || cityId <= 0) {
      return []
    }

    try {
      loadingDistricts.value = true
      // 清除之前的错误状态
      error.value = null

      const cacheKey = CACHE_CONFIG.districts.key(cityId)
      const districtsCache = getDistrictsCache(cityId)

      // 尝试从缓存获取
      if (useCache) {
        const cached = districtsCache.get(cacheKey)
        if (cached && Array.isArray(cached) && cached.length > 0) {
          districtsByCity.set(cityId, cached)
          return cached
        }
      }

      // 从API获取
      const data = await regionOptimizedApi.getDistricts(cityId)

      // 确保数据格式正确
      const validData = Array.isArray(data) ? data : []

      // 存储到按城市分类的Map中
      districtsByCity.set(cityId, validData)

      // 缓存数据
      if (validData.length > 0) {
        districtsCache.set(cacheKey, validData, CACHE_CONFIG.districts.ttl)
      }

      return validData
    } catch (err) {
      // 只有在真正出错时才设置错误信息，空数据或204状态码不算错误
      if (
        err instanceof Error &&
        err.message !== 'No content' &&
        err.message !== 'request canceled' &&
        !err.message.includes('204') &&
        !err.message.includes('ERR_CANCELED')
      ) {
        error.value = '加载区县数据失败'
      }

      // 失败时返回空数组
      return []
    } finally {
      loadingDistricts.value = false
    }
  }

  // 清除缓存
  const clearCache = (): void => {
    provincesCache.clear()
    citiesCacheMap.value.clear()
    districtsCacheMap.value.clear()
    provinces.value = []
    cities.value = []
    districts.value = []
    citiesByProvince.clear()
    districtsByCity.clear()
  }

  // 搜索地区
  const searchRegions = async (
    keyword: string,
    level?: number,
    limit?: number
  ): Promise<OptimizedRegionSearchResult[]> => {
    try {
      error.value = null
      const results = await regionOptimizedApi.searchRegions(keyword, level, limit)
      return results
    } catch (err) {
      error.value = err instanceof Error ? err.message : '搜索地区失败'
      return []
    }
  }

  // 获取完整地址
  const getFullAddress = async (regionId: number): Promise<string> => {
    try {
      error.value = null
      const path = await regionOptimizedApi.getFullPath(regionId)
      return path.path.map(node => node.name).join('')
    } catch (err) {
      error.value = err instanceof Error ? err.message : '获取完整地址失败'
      return ''
    }
  }

  return {
    // 数据
    provinces: regionProvinces,
    cities: regionCities,
    districts: regionDistricts,

    // 按省份存储的城市数据
    citiesByProvince,
    districtsByCity,
    getCitiesForProvince,
    getDistrictsForCity,

    // 加载状态
    loadingProvinces,
    loadingCities,
    loadingDistricts,

    // 错误状态
    error,

    // 方法
    loadProvinces,
    loadCities,
    loadDistricts,
    searchRegions,
    getFullAddress,
    clearCache,
  }
}
